﻿using Serilog;
using Serilog.Configuration;
using Serilog.Core;
using Serilog.Events;

namespace ZCommon;

public delegate void ZLogEventHandle(string level, string message);

public class ZLogSink : ILogEventSink
{
    // 定义日志事件,供外部订阅
    public static event ZLogEventHandle? ZLogEvent;

    // 可选的格式提供器
    private readonly IFormatProvider? _formatProvider;

    public ZLogSink(IFormatProvider? formatProvider)
    {
        _formatProvider = formatProvider;
    }

    // 实现ILogEventSink接口的方法
    public void Emit(LogEvent logEvent)
    {
        // Debug是1级别,只触发高于Debug级别的日志事件
        if ((int) logEvent.Level > 1)
        {
            // 触发日志事件
            ZLogEvent?.Invoke(logEvent.Level.ToString(), logEvent.RenderMessage(_formatProvider));
        }
    }
}

public static class ZLogSinkExtensions
{
    public static LoggerConfiguration ZLogSink(
        this LoggerSinkConfiguration loggerConfiguration,
        IFormatProvider? formatProvider = null)
    {
        return loggerConfiguration.Sink(new ZLogSink(formatProvider));
    }
}

/*
日志使用方法:
Log.Debug("Initialized Driver debug");
Log.Information("Initialized Driver info");
Log.Warning("Initialized Driver warn");
Log.Error("Initialized Driver error");
Log.Fatal("Initialized Driver fatal");
*/
/// <summary>
/// 日志库,会同时输出到控制台和文件
/// </summary>
public static class ZLog
{
    public static void Initialize(string fileName)
    {
        // 创建 Logger 配置
        Log.Logger = new LoggerConfiguration()
            .Enrich.WithThreadId()
            // 设置最低日志级别
            .MinimumLevel.Debug()
            // 输出到控制台
            .WriteTo.Console(
                outputTemplate: "[{Level}]{Timestamp:HH:mm:ss.fff} {ThreadId} {Message}{NewLine}{Exception}")
            .WriteTo.File(
                $"logs/{fileName}.log",
                // 每天滚动
                rollingInterval: RollingInterval.Day,
                // 最大200M
                fileSizeLimitBytes: 200 * 1024 * 1024,
                // 最多30个文件
                retainedFileCountLimit: 30,
                outputTemplate: "[{Level}]{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {ThreadId} {Message}{NewLine}{Exception}"
            )
            .WriteTo.ZLogSink()
            .CreateLogger();

        // ZLogSink.ZLogEvent += (level, message) =>
        // {
        //     Console.WriteLine($"hello {level}: {message}");
        // };
    }
}